﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Xml;
using System.Net;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Configuration;
using Everynet.Models;
namespace Everynet
{
    /// <summary>
    /// Summary description for checkData
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    public class checkData : System.Web.Services.WebService
    {
        #region[Number Based]
        [WebMethod]
        public string NumberBased(string fullnationalnumber, string planID)
        {
            string returnValue = "0";
            if (!String.IsNullOrEmpty(planID) && !String.IsNullOrEmpty(fullnationalnumber))
            {
                returnValue = ServiceTest(Convert.ToInt32(planID), Convert.ToInt64(fullnationalnumber)).ToString();
            }
            return returnValue;
        }
        #region [Strings and Enums]
        String Zone1 = "Zone 1";
        String Zone2 = "Zone 2";
        String Zone3 = "Zone 3";
        String OffNet = "OffNet";
        String OnNet = "OnNet";
        String Completed = "Completed";
        String Soapfault = "<soap:Fault>";
        String Soappass = "SQ Response: Pass";
        
        public enum enumReturnvalue
        {
            NoServiceExists = -1,
            NoServiceExistsAndShowOtherService = 0,
            ServiceExistsForIt = 1,
            ServiceExistsAndDSLAlreadyExists = 2,
            ServiceNakedDSL = 4
        }
        #endregion

        /// <summary>
        /// Basic concept use:
        ///1.) if return  0 means no service exists for it and show other service if exists in that area.
        ///2.) if return  1 means service exists for it.(dsl already not exists.)
        ///3.) if return  2 means service exists and also dsl is already exists.
        ///4.) if return  4 means Naked DSL  and send email to Vendor.
        ///5.) if return  -1 means no service exist for it and send email to signups@everynet.com.au.
        ///OffNet: 0383609145
        ///OnNet: 0296494901
        ///UnabletoProcess: 0397946171
        ///normal:0261004750
        ///string strServiceNumber = "0261004750";
        /// </summary>
        /// <param name="planID"></param>
        /// <param name="fullnationalnumber"></param>
        /// <returns></returns>
        public Int32 ServiceTest(Int32 planID, Int64 fullnationalnumber)
        {
            String getFinalResult = string.Empty;
            Int32 getFinalResutINT = (int)(enumReturnvalue.NoServiceExists); // -1= no Service Exists for it,Zero=Service not exist:show other services if exists,One=Service Exist.(For National ADSL2(3) and Regional ADSL2(5))
            string strServiceNumber = fullnationalnumber.ToString();

            Int32 NationalADSL2 = (int)@signUpModel.enumPlanNames.NationalADSL2;//(3)
            Int32 NakedDSL = (int)@signUpModel.enumPlanNames.NakedDSL;//(4)
            Int32 RegionalADSL2 = (int)@signUpModel.enumPlanNames.RegionalADSL2;//(5)
            
            Int32 ADSLHomephone = (int)@signUpModel.enumPlanNames.BundleADSLHomephone;//(8)
            Int32 ADSLVOIP = (int)@signUpModel.enumPlanNames.BundleADSLVOIP;//(9)
            Int32 ADSLHomephonePlusVOIP = (int)@signUpModel.enumPlanNames.BundleADSLHomephonePlusVOIP;//(10)
            try
            {
                //Inner code will only work if they are plan of types:National ADSL2(3) and Regional ADSL2(5)
                //We will check here bundles also(Bundle ADSL Homephone(8), Bundle ADSL VOIP(9), Bundle ADSL Homephone Plus VOIP(10))
                if ((planID > 0) && (planID == NationalADSL2 || planID == RegionalADSL2 || planID == ADSLHomephone || planID == ADSLVOIP || planID==ADSLHomephonePlusVOIP)) //National ADSL2(3) and Regional ADSL2(5)
                {
                    string getXML = serviceStaging(strServiceNumber); //WORKING
                    XmlDocument xd = new XmlDocument();
                    xd.LoadXml(getXML);

                    //if there is an error "Automated qualification is currently unavailable for your supplied details" and forward email to signups@everynet.com.au
                    if (getXML.Contains(Soapfault))
                    {
                        #region [Get Fault specific Value]
                        getFinalResutINT = (int)(enumReturnvalue.NoServiceExists);
                        #endregion
                    }
                    else if (getXML.Contains(Soappass))
                    {
                        if (planID != 0)
                        {
                            getFinalResutINT = GetSuccessMessage(xd, planID);//0,1 or 2 return from here.
                        }
                    }
                }

                else if ((planID > 0) && (planID == NakedDSL)) //Naked DSL(4) --Send email, notify them "Service qualification is being processed"
                {
                    getFinalResutINT = (int)(enumReturnvalue.ServiceNakedDSL);
                }
                return getFinalResutINT;
            }
            catch
            {
                return (int)(enumReturnvalue.NoServiceExists);
            }


        }
       
        /// <summary>
        /// Chart:
        ///This is the Zone chart
        ///OnNet                                     ||    Offnet
        ///National ADSL 2 (No Zone required)        ||    National ADSL 2 (Zone1) 
        ///                                          ||    Regional ADSL(Zone2,Zone3)
        ///check the Zone of the line.
        ///Zone is only in case of 'Offnet', class is only in case of 'OnNet'.
        ///1 & 2, if they have selected something that is unavailable present them the options for available plans,
        ///if there is an error "Automated qualification is currently unavailable for your supplied details" 
        ///and forward email to signups@everynet.com.au
        /// </summary>
        /// <param name="xd"></param>
        /// <param name="planID"></param>
        /// <returns></returns>
        public Int32 GetSuccessMessage(XmlDocument xd, Int32 planID)
        {
            string MainQuery = "/soap:Envelope/soap:Body/ns2:ServiceQualificationResponse/";
            Int32 NationalADSL2 = (int)@signUpModel.enumPlanNames.NationalADSL2;//(3)
            Int32 RegionalADSL2 = (int)@signUpModel.enumPlanNames.RegionalADSL2;//(5)

            Int32 ADSLHomephone = (int)@signUpModel.enumPlanNames.BundleADSLHomephone;//(8)
            Int32 ADSLVOIP = (int)@signUpModel.enumPlanNames.BundleADSLVOIP;//(9)
            Int32 ADSLHomephonePlusVOIP = (int)@signUpModel.enumPlanNames.BundleADSLHomephonePlusVOIP;//(10)

            #region [Get Specific Node Value]
            Int32 returnSuccess = (int)(enumReturnvalue.NoServiceExists);
            XmlNamespaceManager manager = new XmlNamespaceManager(xd.NameTable);
            manager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            manager.AddNamespace("ns2", "http://www.vocus.net.au/Wholesale/Schemas/External/1.0/DSL/Provisioning/ServiceQualification.xsd");
            string query = MainQuery+"StatusDescription";

            string getBodyXML = string.Empty;
            string getNetXML = string.Empty;
            string getNetAlready = string.Empty;
            string getOffNetZone = string.Empty;
            string getOnNetPass = string.Empty;
            string getOffNetZonePass = string.Empty;

            XmlNodeList xnList = xd.SelectNodes(query, manager);
            foreach (XmlNode xn in xnList)
            {
                getBodyXML = xn.InnerText;
            }
            //1. OffNet ("Transmission loss too high") 2. OnNet
            if (getBodyXML == Completed)
            {
                //check it is net(OnNet/OffNet)
                string queryNet = MainQuery+"Net";
                XmlNodeList xnListNet = xd.SelectNodes(queryNet, manager);
                foreach (XmlNode xnNet in xnListNet)
                {
                    getNetXML = xnNet.InnerText;
                }

                //check DSL Already exist on this Line:
                string queryAlready = MainQuery+"DSLFound";
                XmlNodeList xnListAlready = xd.SelectNodes(queryAlready, manager);
                foreach (XmlNode xnNetAlready in xnListAlready)
                {
                    getNetAlready = xnNetAlready.InnerText;
                }
                

                //If Net is not null or blank
                if (!String.IsNullOrEmpty(getNetXML))
                {
                    //<Net>OffNet</Net>
                    //database ids --National ADSL2(3), Regional ADSL2(5)
                    if (getNetXML == OffNet) //National ADSL 2 (Zone1), Regional ADSL(Zone 2,Zone 3)
                    {
                        string queryZone = MainQuery+"Result/Zone";
                        XmlNodeList xnListZone = xd.SelectNodes(queryZone, manager);
                        foreach (XmlNode xnNetZone in xnListZone)
                        {
                            getOffNetZone = xnNetZone.InnerText;
                        }

                        string queryZonePass = MainQuery+"Result/Pass";
                        XmlNodeList xnListZonePass = xd.SelectNodes(queryZonePass, manager);
                        foreach (XmlNode xnNetZonePass in xnListZonePass)
                        {
                            getOffNetZonePass = xnNetZonePass.InnerText;
                        }

                        //--National ADSL2(3), Regional ADSL2(5)
                        //<Zone>Zone 2</Zone>
                        if ((((planID == NationalADSL2) || (planID == ADSLHomephone) || (planID == ADSLVOIP) || (planID == ADSLHomephonePlusVOIP)) && (getOffNetZone == Zone1) && (getOffNetZonePass == "1")) || ((planID == RegionalADSL2) && (getOffNetZone == Zone2 || getOffNetZone == Zone3) && (getOffNetZonePass == "1") && getNetAlready == "1"))
                        {
                            returnSuccess = (int)(enumReturnvalue.ServiceExistsAndDSLAlreadyExists);
                        }
                        else if ((((planID == NationalADSL2) || (planID == ADSLHomephone) || (planID == ADSLVOIP) || (planID == ADSLHomephonePlusVOIP)) && (getOffNetZone == Zone1) && (getOffNetZonePass == "1")) || ((planID == RegionalADSL2) && (getOffNetZone == Zone2 || getOffNetZone == Zone3) && (getOffNetZonePass == "1")))
                        {
                            returnSuccess = (int)(enumReturnvalue.ServiceExistsForIt);
                        }

                    }
                    //database ids --National ADSL2(3)
                    else if (getNetXML == OnNet) //National ADSL 2 (No Zone required)
                    {
                        string queryPass = MainQuery+"Result/Pass";
                        XmlNodeList xnListPass = xd.SelectNodes(queryPass, manager);
                        foreach (XmlNode xnNetPass in xnListPass)
                        {
                            getOnNetPass = xnNetPass.InnerText;
                        }
                        //--National ADSL2(3)
                        if (getOnNetPass == "1" && ((planID == NationalADSL2) || (planID == ADSLHomephone) || (planID == ADSLVOIP) || (planID == ADSLHomephonePlusVOIP)) && getNetAlready == "1")     //<Pass>1</Pass><DSLFound>1</DSLFound>
                        {
                            returnSuccess = (int)(enumReturnvalue.ServiceExistsAndDSLAlreadyExists);
                        }
                        else if (getOnNetPass == "1" && ((planID == NationalADSL2) || (planID == ADSLHomephone) || (planID == ADSLVOIP) || (planID == ADSLHomephonePlusVOIP)))       //<Pass>1</Pass>
                        {
                            returnSuccess = (int)(enumReturnvalue.ServiceExistsForIt);
                        }
                        else if (getOnNetPass == "1" && planID == RegionalADSL2) //Qualification fail, customer can select this plan.
                        {
                            returnSuccess = (int)(enumReturnvalue.NoServiceExistsAndShowOtherService);
                        }

                    }
                }

                return returnSuccess;

            }
            else   //<StatusDescription>Unable to Process</StatusDescription>
            {
                return (int)(enumReturnvalue.NoServiceExists);
            }
            #endregion
        }
       
        public string GetFaultMessage(XmlDocument xd)
        {
            #region [Get Fault specific Value]
            XmlNamespaceManager managerFault = new XmlNamespaceManager(xd.NameTable);
            managerFault.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            managerFault.AddNamespace("ns2", "http://www.vocus.net.au/Wholesale/Schemas/External/1.0/DSL/Provisioning");
            string queryFault = "/soap:Envelope/soap:Body/soap:Fault/detail/ns2:ServiceFault/faultDescription";
            string getBodyXMLFault = string.Empty;
            XmlNodeList xnListFault = xd.SelectNodes(queryFault, managerFault);
            foreach (XmlNode xnFault in xnListFault)
            {
                getBodyXMLFault = xnFault.InnerText;
            }
            return getBodyXMLFault;
            #endregion
        }
       
        public string serviceStaging(string ServiceNumber)
        {
            //check ServiceNumber leading zero will not Ignore.
            Int64 serviceNum = Convert.ToInt64(ServiceNumber);
            string ServiceNumberfull = serviceNum.ToString("0000000000");
            string Urlpath = ConfigurationManager.AppSettings["ServiceQualificationAPIUrl"].ToString();
            string UrlAction = ConfigurationManager.AppSettings["ServiceQualificationAPIAction"].ToString();
            string getXml = @"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" 
                               xmlns:ser=""http://www.vocus.net.au/Wholesale/Schemas/External/1.0/DSL/Provisioning/ServiceQualification.xsd"">
                                  <soapenv:Header>
                                  <ser:SoapHeaderMsg>
                                     <ContextId>ServiceQualification-Success-01</ContextId>
                                  </ser:SoapHeaderMsg>
                               </soapenv:Header>                               
                                 <soapenv:Body>
                                  <ser:ServiceQualificationRequest>
                                     <FNN>" + ServiceNumberfull + @"</FNN>
                                  </ser:ServiceQualificationRequest>
                               </soapenv:Body>
                            </soapenv:Envelope>";
            return ExecuteCommon(getXml, UrlAction, Urlpath);
        }
       
        public string ExecuteCommon(string xml, string soapaction, string url1)
        {
            String certPath = Server.MapPath("~/cert/everynet.uat.p12");
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(@url1);
            webRequest.Headers.Add("SOAPAction", soapaction);
            webRequest.ContentType = "text/xml";
            webRequest.Method = "POST";
            X509Certificate2 cert = new X509Certificate2(certPath, "busty54AYe%");
            webRequest.ClientCertificates.Add(cert);
            webRequest.PreAuthenticate = true;
            XmlDocument soapEnvelopeXml = new XmlDocument();
            soapEnvelopeXml.LoadXml(xml);
            using (Stream stream = webRequest.GetRequestStream())
            {
                soapEnvelopeXml.Save(stream);
            }
            string returnXML = String.Empty;
            try
            {
                using (var response = webRequest.GetResponse() as HttpWebResponse)
                {
                    if (webRequest.HaveResponse && response != null)
                    {
                        using (var reader = new StreamReader(response.GetResponseStream()))
                        {
                            string result = reader.ReadToEnd();
                            returnXML = result;
                        }
                    }

                }
            }
            catch (WebException wex)
            {
                if (wex.Response != null)
                {
                    using (var errorResponse = (HttpWebResponse)wex.Response)
                    {
                        using (var reader = new StreamReader(errorResponse.GetResponseStream()))
                        {
                            string error = reader.ReadToEnd();
                            returnXML = error;
                        }
                    }
                }
            }
            return returnXML;
        }
        #endregion

        #region[Address Based]
        [WebMethod]
        public string AdddressBased(string Address)
        {
            if (Address == "fail")
            {
                return "0"; //"UnAvailable";
            }
            else
            {
                return "1"; //"Available";
            }
        }
        #endregion

    }
}
